<script setup>
import { onMounted, reactive, defineComponent, computed, ref } from "vue"
import copyw from "@/components/copy.vue"
import { message } from "ant-design-vue"
import Easytxt from "@/components/easytxt.vue"
onMounted(() => {})

const state = reactive({
    checked: "行比较(自动顺序)",
    cText: "",
})
const left_editor = ref(null)
const right_editor = ref(null)
function clear() {
    left_editor.value.setContent("")
    right_editor.value.setContent("")
}

function getHighLightDifferent(a, b) {
    // 创建二维数组
    const dp = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0))

    // 动态规划找出最长公共子序列
    for (let i = 1; i <= a.length; i++) {
        for (let j = 1; j <= b.length; j++) {
            if (a[i - 1] === b[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1])
            }
        }
    }

    // 找出最长公共子序列
    let lcs = ""
    let i = a.length,
        j = b.length
    while (i > 0 && j > 0) {
        if (a[i - 1] === b[j - 1]) {
            lcs = a[i - 1] + lcs
            i--
            j--
        } else if (dp[i - 1][j] > dp[i][j - 1]) {
            i--
        } else {
            j--
        }
    }

    // 标记不同部分
    let result = ""
    i = j = 0
    for (let k = 0; k < lcs.length; k++) {
        while (a[i] !== lcs[k]) {
            if (a[i] == "\n") {
                result += result += `<span style='background-color:red;color:white'>[回车]</span>`
                i++
            } else {
                result += `<span style='background-color:red;color:white'>${a[i++]}</span>`
            }
        }
        while (b[j] !== lcs[k]) {
            if (b[j] == "\n") {
                result += `<span style='background-color:green;color:white'>[回车]</span>`
                j++
            } else {
                result += `<span style='background-color:green;color:white'>${b[j++]}</span>`
            }
        }
        if (lcs[k] == "\n") {
            result += `<br>`
        } else {
            result += lcs[k]
        }
        i++
        j++
    }
    while (i < a.length) {
        if (a[i] == "\n") {
            result += `<span style='background-color:red;color:white'>[回车]</span>`
            i++
        } else {
            result += `<span style='background-color:red;color:white'>${a[i++]}</span>`
        }
    }
    while (j < b.length) {
        if (b[j] == "\n") {
            result += `<span style='background-color:green;color:white'>[回车]</span>`
            j++
        } else {
            result += `<span style='background-color:green;color:white'>${b[j++]}</span>`
        }
    }

    return result
}

function compare() {
    const t1 = left_editor.value.getContent() || ""
    const t2 = right_editor.value.getContent() || ""

    let l1 = [],
        l2 = []
    if (t1) {
        l1 = t1.split("\n")
    }
    if (t2) {
        l2 = t2.split("\n")
    }
    const data1 = { red: [], green: [], yellow: [] }
    const data2 = { red: [], green: [], yellow: [] }
    if (state.checked == "行比较(按当前顺序)") {
        const ll = Math.min(l1.length, l2.length)
        for (var i = 0; i < ll; i++) {
            if (l1[i] !== l2[i]) {
                data1.red.push(i + 1)
                data2.red.push(i + 1)
            }
        }
        if (l1.length > l2.length) {
            for (var i = ll; i < l1.length; i++) {
                data1.green.push(i + 1)
            }
        } else if (l1.length < l2.length) {
            for (var i = ll; i < l2.length; i++) {
                data2.green.push(i + 1)
            }
        }
    } else if (state.checked == "行比较(自动顺序)") {
        const d1_map = {}
        const d2_map = {}
        for (var i = 0; i < l1.length; i++) {
            d1_map[l1[i]] = i + 1
        }
        for (var i = 0; i < l2.length; i++) {
            d2_map[l2[i]] = i + 1
        }
        const keys1 = Object.keys(d1_map)
        const keys2 = Object.keys(d2_map)
        for (var i = 0; i < keys1.length; i++) {
            if (keys1[i].trim() == "") {
                continue
            }
            if (!d2_map[keys1[i]]) {
                data1.green.push(i + 1)
            }
        }
        for (var i = 0; i < keys2.length; i++) {
            if (keys2[i].trim() == "") {
                continue
            }
            if (!d1_map[keys2[i]]) {
                data2.green.push(i + 1)
            }
        }
    } else if (state.checked == "单行比较") {
        const da = getHighLightDifferent(t1, t2)
        state.cText = da.replace(/\n/g, "<br>")
        if (t1 == cText) {
            message.success("两个文本相同")
        }
        return
        // console.log(da)
    }
    left_editor.value.setColor(data1)
    right_editor.value.setColor(data2)
    if (
        data1.red.length == 0 &&
        data2.red.length == 0 &&
        data1.green.length == 0 &&
        data2.green.length == 0 &&
        data1.yellow.length == 0 &&
        data2.yellow.length == 0
    ) {
        message.success("两个文本相同")
    } else {
        message.info("两个文本存在不同")
    }
}
</script>
<template>
    <div class="k">
        <div class="content">
            <h1 class="f_row" style="justify-content: flex-start">
                简易文本比较<copyw title="简易文本比较" ckey="txtc"></copyw>
            </h1>
            <div class="f_row" style="gap: 12px; justify-content: flex-start; margin-bottom: 8px">
                <a-button type="primary" size="small" @click="compare">比较</a-button>
                <a-button @click="clear" size="small">清空</a-button>
                <a-radio-group
                    v-model:value="state.checked"
                    :options="['行比较(按当前顺序)', '行比较(自动顺序)', '单行比较']"
                />
            </div>
            <div style="height: calc(100vh - 160px); gap: 20px" class="f_row">
                <Easytxt
                    ref="left_editor"
                    :func="{
                        copy: true,
                        clear: true,
                        sortTxt: true,
                        clearline: true,
                        clearlineBlank: true,
                        tags: true,
                        remark: true,
                    }"
                ></Easytxt>
                <Easytxt
                    ref="right_editor"
                    :func="{
                        copy: true,
                        clear: true,
                        sortTxt: true,
                        clearline: true,
                        clearlineBlank: true,
                        tags: true,
                        remark: true,
                    }"
                ></Easytxt>
            </div>
            <div
                v-if="state.cText && state.cText.length != '' && state.checked == '单行比较'"
                v-html="state.cText"
                style="
                    margin-top: 12px;
                    border: 1px solid #fafafa;
                    padding: 8px 12px;
                    overflow: hidden;
                    word-wrap: break-word;
                    word-break: break-all;
                    white-space: pre-wrap;
                "
            ></div>
        </div>
    </div>
</template>
<style scoped>
.content {
    max-width: 1280px;
    margin: 0 auto;
    width: 100%;
    padding: 32px;
    gap: 24px;
    align-items: flex-start;
    background-color: var(--Neutral-11);
    height: 100%;
    justify-content: flex-start;
    position: relative;
    border-radius: 8px;
}

:where(.k) {
    height: 100%;
    background-color: var(--page-bg-color);
    padding: 16px;
}

h1 {
    color: var(--character-85);
    font-size: 24px;
    margin-bottom: 16px;
}

:deep(.ant-radio-group) {
    color: var(--character-75);
}

:deep(.ant-radio-wrapper) {
    color: var(--character-75);
}

:deep(.ant-radio-checked .ant-radio-inner) {
    border-color: var(--Geek-Blue-5);
    background-color: var(--Geek-Blue-5);
}

:deep(.ant-button) {
    background-color: var(--element-bg-color);
    border-color: var(--Neutral-9);
    color: var(--character-85);
}

:deep(.ant-button-primary) {
    background-color: var(--Geek-Blue-5);
    border-color: var(--Geek-Blue-5);
    color: var(--character-100);
}

:deep(.ant-button:hover) {
    border-color: var(--Geek-Blue-4);
    color: var(--Geek-Blue-4);
}

:deep(.ant-button-primary:hover) {
    background-color: var(--Geek-Blue-4);
    border-color: var(--Geek-Blue-4);
    color: var(--character-100);
}
</style>
